#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include "webrtc_aec.h"
#include "audio_aec.h"
#ifdef DMALLOC
#include <imp/dmalloc.h>
#endif
#include "profiles/profiles_management.h"
#define AP_AEC_MAGIC (('a'<<24)|('e'<<16)|('c'<<8)|('0'))

char profile_buff[101] = "";
char aec_far[101] = "";
char aec_near[101] = "";
char aec_filter[101] = "";
#define  TAG "audio_aec"
struct aec_handle {
	unsigned int magic;
	int sample_rate;
};

FILE *fp_far = NULL;
FILE *fp_near = NULL;
FILE *fp_filter = NULL;
void *audio_process_aec_create(int sample_rate, char *profile_path)
{
	struct aec_handle *ah;
	ah = (struct aec_handle *)malloc(sizeof(struct aec_handle));
	if (NULL == ah) {
		printf("err: %s,%d-%s\n", __func__, __LINE__, strerror(errno));
		return NULL;
	}
	ah->sample_rate = sample_rate;
	ah->magic = AP_AEC_MAGIC;
	ingenic_apm_init(sample_rate, profile_path);
	if(read_profile(profile_path, "PATH","AEC_PATH", profile_buff) < 0){
		printf("cannot find the value of PATH:AEC_PATH,normal audio library\n");
	}else if(!strcmp(profile_buff, "")){
		printf("PATH:AEC_PATH is empty,normal audio library\n");
	}else {
		printf("can find the value of PATH:AEC_PATH,debug audio library\n");
		sprintf(aec_far,"%s%s",profile_buff,"far.pcm");
		sprintf(aec_near,"%s%s",profile_buff,"near.pcm");
		sprintf(aec_filter,"%s%s",profile_buff,"filter.pcm");
		fp_far = fopen(aec_far,"wb+");
		fp_near = fopen(aec_near,"wb+");
		fp_filter = fopen(aec_filter,"wb+");
	}
	return ah;
}

int audio_process_aec_process(void *aec_handle, struct aec_process_param *param)
{
	int i = 0;
	short *far_frame = NULL;
	short *near_frame = NULL;
	short *filter_frame = NULL;
	struct aec_handle *ah = (struct aec_handle *)aec_handle;
	if (AP_AEC_MAGIC != ah->magic) {
		printf("err aec handle error %p\n", ah);
		return -1;
	}

	if(fp_far != NULL)
		fwrite(param->far,1,param->size,fp_far);
	if(fp_near != NULL)
		fwrite(param->near,1,param->size,fp_near);
	/* aec process 10ms data once */
	int dsize = param->size;
	int aecsize = ah->sample_rate*sizeof(short)/100;
	for (i = 0; i < dsize/aecsize; i++) {
		far_frame = (short *)(param->far+aecsize*i);
		near_frame = (short *)(param->near+aecsize*i);
		filter_frame = (short *)(param->near+aecsize*i);
		ingenic_apm_set_far_frame(far_frame);
		ingenic_apm_set_near_frame(near_frame, filter_frame);
	}
	if(fp_filter != NULL)
		fwrite(param->filter,1,param->size,fp_filter);
	return 0;
}

int audio_process_aec_free(void * aec_handle)
{
	struct aec_handle *ah = (struct aec_handle *)aec_handle;
	if (AP_AEC_MAGIC != ah->magic) {
		printf("err aec handle free error %p\n", ah);
		return -1;
	}
	ingenic_apm_destroy();
	free(ah);

	if(fp_far != NULL)
		fclose(fp_far);
	if(fp_near != NULL)
		fclose(fp_near);
	if(fp_filter != NULL)
		fclose(fp_filter);
	return 0;
}
